﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.IO.Ports;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace SerialToUdp
{
    /// <summary>
    /// SQLite 助手
    /// </summary>
    public sealed class SQLiteHelper
    {
        private const string ConnectionStr = "Data Source=sqlite.db";
        private static SQLiteHelper _instance;
        private static readonly object Locker = new object();

        private SQLiteHelper()
        {
        }

        /// <summary>
        /// 获取实例
        /// </summary>
        /// <returns></returns>
        public static SQLiteHelper GetInstance()
        {
            if (_instance == null)
            {
                lock (Locker)
                {
                    if (_instance == null)
                    {
                        _instance = new SQLiteHelper();
                    }
                }
            }

            return _instance;
        }

        /// <summary>
        /// 获取数据表
        /// </summary>
        /// <param name="cmdText"> 需要执行的命令文本 </param>
        /// <returns> 一个数据表集合 </returns>
        public DataTable GetDataTable(string cmdText)
        {
            var dt = new DataTable();

            try
            {
                using (var conn = new SQLiteConnection(ConnectionStr))
                {
                    conn.Open();
                    var cmd = new SQLiteCommand(conn) { CommandText = cmdText };
                    using (var reader = cmd.ExecuteReader())
                    {
                        dt.Load(reader);
                    }
                }
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }

            return dt;
        }

        /// <summary>
        /// 执行非查询命令
        /// </summary>
        /// <param name="cmdText"> 需要执行的命令文本 </param>
        /// <returns> 返回更新的行数 </returns>
        public int ExecuteNonQuery(string cmdText)
        {
            using (var conn = new SQLiteConnection(ConnectionStr))
            {
                conn.Open();
                var cmd = new SQLiteCommand(conn) { CommandText = cmdText };
                var rowsUpdated = cmd.ExecuteNonQuery();

                return rowsUpdated;
            }
        }

        /// <summary>
        /// 执行检索单项命令
        /// </summary>
        /// <param name="cmdText"> 需要执行的命令文本 </param>
        /// <returns> 一个字符串 </returns>
        public string ExecuteScalar(string cmdText)
        {
            using (var conn = new SQLiteConnection(ConnectionStr))
            {
                conn.Open();
                var cmd = new SQLiteCommand(conn) { CommandText = cmdText };
                var value = cmd.ExecuteScalar();

                if (value != null)
                {
                    return value.ToString();
                }
            }

            return "";
        }
    }
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        SerialPort serialPort = new SerialPort("COM5", 115200);
        public MainWindow()
        {
            InitializeComponent();




            SQLiteHelper sql = SQLiteHelper.GetInstance();

            sql.ExecuteNonQuery("update table1 set value = 'COM1' where key = 'com'");

            string str = sql.ExecuteScalar("select value from table1 where key = 'com'");
            Console.WriteLine("com:" + str);
            str = sql.ExecuteScalar("select value from table1 where key = 'ip'");
            Console.WriteLine("ip:" + str);

            DataTable tb = sql.GetDataTable("select * from table1");
            dataGrid1.DataContext = tb;


            //连接数据库
            //SQLiteConnection m_dbConnection = new SQLiteConnection("Data Source=sqlite.db;Version=3;");
            //m_dbConnection.Open();
            ////表不存在自动创建
            //string sql =
            //"CREATE TABLE IF NOT EXISTS table1(" +
            //    "id INTEGER PRIMARY KEY AUTOINCREMENT," +
            //    "key VARCHAR( 50 )," +
            //    "value VARCHAR( 50 )," +
            //    "des VARCHAR( 200 )" +
            //    "); " +
            //    "INSERT INTO 'main'.'table1' VALUES(1,'com', 1, 3);" +
            //    "INSERT INTO 'main'.'table1' VALUES(2,'ip', 2, 3);" +
            //    "INSERT INTO 'main'.'table1' VALUES(3,'endport', 3, 3);" +
            //    "INSERT INTO 'main'.'table1' VALUES(4,'localport', 4, 3);" +
            //    "PRAGMA foreign_keys = ON;"
            //;
            //SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
            //command.ExecuteNonQuery();
            //m_dbConnection.Close();
            //读取配置
            //string path = "sqlite.db";
            //SQLiteConnection con = new SQLiteConnection("data source=" + path);
            //con.Open();
            //SQLiteCommand cmd = cn.CreateCommand();

            // cmd.CommandText = "PRAGMA table_info('table1')";

            //创建SQL语句
            //string sql = "select * from table1 where key='com'";
            //string sql = "select count(*) from table1";
            ////创建命令对象
            //using (SQLiteCommand cmd = new SQLiteCommand(sql, con))
            //{
            //    int i = cmd.ExecuteScalar();
            //    using (SQLiteDataReader reader = cmd.ExecuteReader())
            //    {

            //        if (reader.HasRows)
            //        {
            //            while (reader.Read())
            //            {
            //                Console.WriteLine(reader.GetInt32(0) + " , " + reader.GetString(1) + reader.GetString(2));
            //            }
            //        }
            //    }
            //}
        }

        Socket socket1;
        IPEndPoint ipEndPoint;
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //开启串口
            serialPort.DataReceived += SerialPort_DataReceived;
            serialPort.Open();

            socket1 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            ipEndPoint = new IPEndPoint(IPAddress.Parse("192.168.31.123"), 18666);
            socket1.Bind(new IPEndPoint(ipEndPoint.Address, 8091));

            //Thread udpThread = new Thread(UdpFunc);
            //udpThread.Start();

            //UdpClient client = new UdpClient(new IPEndPoint(IPAddress.Any, 18666));//端口要与发送端相同
            Thread thread = new Thread(receiveUdpMsg);//用线程接收，避免UI卡住
            thread.IsBackground = true;
            thread.Start();
        }

        private void receiveUdpMsg()
        {
            IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
            EndPoint endPoint = (EndPoint)(sender);
            //定义接收池字符串
            string StringBuf = string.Empty;
            while (true)
            {
                try
                {
                    //socket被关闭则退出
                    if (socket1 == null) return;

                    //缓冲区没有数据跳过
                    int count = socket1.Available;
                    if (count <= 0) continue;

                    byte[] bytes = new byte[count];
                    int length = socket1.ReceiveFrom(bytes, ref endPoint);
                    serialPort.Write(bytes, 0, length);
                }
                catch
                {
                    SetTextCallback d = new SetTextCallback(SetError);   // 托管调用
                    this.Dispatcher.Invoke(d, new object[] { "远端主机未开启" });
                }
            }
        }

        private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            byte[] ReDatas = new byte[serialPort.BytesToRead];
            //从串口读取数据
            serialPort.Read(ReDatas, 0, ReDatas.Length);
            //解码与显示
            SetTextCallback d = new SetTextCallback(SetText);   // 托管调用
            this.Dispatcher.Invoke(d, new object[] { Encoding.ASCII.GetString(ReDatas) });



            socket1.SendTo(ReDatas, ipEndPoint);

            // socket1.Disconnect();
        }

        delegate void SetTextCallback(string text);
        private void SetText(string text)
        {
            if (text.Contains("!"))
                text = text.Replace("!", "!\r\n");
            recive.Text += text;
            recive.ScrollToEnd();
        }
        private void SetError(string text)
        {
            labelerror.Content = text;
        }
    }
}
